package com.cyys.modules.system.controller;

import com.baidu.ueditor.ActionEnter;
import com.cyys.common.ql.AR;
import com.cyys.common.ql.AjaxJson;
import com.cyys.common.thirdInterface.aliyun.OssUtil;
import com.cyys.common.thirdInterface.aliyun.VodUtil;
import com.cyys.common.utils.StringUtil;
import com.cyys.common.utils.file.FileUpload;
import com.cyys.common.utils.file.FileUtil;
import com.cyys.common.utils.file.ImageUtil;
import com.cyys.modules.core.controller.BaseAction;
import com.cyys.modules.core.sysParam.SystemConfigureUtil;
import com.cyys.modules.core.sysParam.SystemConstants;
import com.cyys.modules.system.model.file.FileEntry;
import com.cyys.modules.system.model.user.User;
import com.cyys.modules.system.service.file.FileEntryService;
import lombok.Cleanup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("/file")
public class UploadAction extends BaseAction {

	private static Logger logger = LoggerFactory.getLogger(UploadAction.class);

	@Autowired
	private FileEntryService fileEntryService;

	// 文件的目录名
	private String dirName = "/images";

	/**
	 * @param dirId
	 * @param storeMode 存储模式，oss/vod，vod视频点播
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@PostMapping(value = "/uploadFile")
	public AR uploadFile(HttpServletRequest request, String dirId, String storeMode) throws Exception {
		Map<String, String> extMap = new HashMap<String, String>();
		extMap.put("images", SystemConfigureUtil.get(SystemConstants.FILE_IMAGES));
		extMap.put("medias",  SystemConfigureUtil.get(SystemConstants.FILE_MEDIAS));
		extMap.put("files",  SystemConfigureUtil.get(SystemConstants.FILE_FILES));
		extMap.put("other",  SystemConfigureUtil.get(SystemConstants.FILE_OTHER));
		// 文件上传路径
		String basePath = SystemConfigureUtil.get(SystemConstants.FILE_ROOT_PATH);
		// 文件最大长度
		Long maxSize = Long.parseLong(SystemConfigureUtil.get(SystemConstants.FILE_MAXSIZE)); //单位字节
		if("vod".equals(storeMode)){
			maxSize= 5368709120L; //5G
		}
		AjaxJson aj = new AjaxJson();
		// long startTime = System.currentTimeMillis();
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
				request.getSession().getServletContext());
		// 获取内容类型
		String contentType = request.getContentType();
		int contentLength = request.getContentLength();

		if (contentType == null || !contentType.startsWith("multipart")) {
			return AR.failed("请求不包含multipart/form-data流");
			// errorInfo = "请求不包含multipart/form-data流";
		} else if (maxSize < contentLength) { //contentLength的单位是字节
			return AR.failed("上传文件大小超出文件最大大小，最大大小为" + maxSize);
		} else if (!multipartResolver.isMultipart(request)) {
			return AR.failed("未选择文件");
		} else{
			// asList(fileType.split(",")).contains(fileExt)
			// 将request变成多部分request
			MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
			// 获取multiRequest 中所有的文件名
			Iterator<String> iter = multiRequest.getFileNames();
			// 检查扩展名，并获取存储路径
			while (iter.hasNext()) {
				MultipartFile file = multiRequest.getFile(iter.next());
				if (file != null) {
					String fileExt = file.getOriginalFilename()
							.substring(file.getOriginalFilename().lastIndexOf(".") + 1).toLowerCase();
					if (Arrays.<String> asList(extMap.get("images").split(",")).contains(fileExt)) {
						dirName = "/images";
					} else if (Arrays.<String> asList(extMap.get("medias").split(",")).contains(fileExt)) {
						dirName = "/medias";
					} else if (Arrays.<String> asList(extMap.get("files").split(",")).contains(fileExt)) {
						dirName = "/files";
					} else if (Arrays.<String> asList(extMap.get("other").split(",")).contains(fileExt)) {
						dirName = "/other";
					} else {
						return AR.failed("此文件类型不允许上传。");
					}
				}
			}
			List<FileEntry> fileEntryList = new ArrayList<FileEntry>();
			Date currentDate = new Date();
			iter = multiRequest.getFileNames();
			// 上传文件
			while (iter.hasNext()) {
				// 一次遍历所有文件
				MultipartFile file = multiRequest.getFile(iter.next());
				if (file != null) {
					String videoId= null;//上传至视频点播的音视频ID
					boolean isVodMode= "vod".equals(storeMode) && dirName.indexOf("medias")>-1;
					// basePath + dirName + yyyy/MM/dd + newFileName
					String fileExt = file.getOriginalFilename()
							.substring(file.getOriginalFilename().lastIndexOf(".") + 1).toLowerCase();
					SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
					String newFileName = df.format(currentDate) + "_" + new Random().nextInt(1000) + "." + fileExt;
					df = new SimpleDateFormat("yyyy/MM/dd");

					String fileUrl = dirName + "/" + df.format(currentDate) + "/" + newFileName;

					int uploadMode = Integer.valueOf(SystemConfigureUtil.get(SystemConstants.FILE_UPLOAD_MODE));
					// 上传
					switch (uploadMode){
						//mode为1时上传至OSS
						case 1:{
							if(isVodMode){//音视频上传至阿里云视频点播
								videoId= VodUtil.uploadVideo(file.getOriginalFilename(), file.getOriginalFilename(), file.getInputStream());
							}else{
								if (StringUtil.isBlank(basePath)) {
									basePath = request.getSession().getServletContext().getRealPath("") + "/files";
								}
								String path = basePath + dirName + "/" + df.format(currentDate);
								FileUpload.createPath(path, newFileName);
								try {
									OssUtil.upLoadFile(file.getInputStream(),fileUrl.substring(1,fileUrl.length()));
								}catch (IOException e){
									return AR.failed("文件上传失败：" + e.getMessage());
								}
							}
						}break;
						//mode为2时上传至本地服务器
						case 2:{
							try {
								if (StringUtil.isBlank(basePath)) {
									basePath = request.getSession().getServletContext().getRealPath("") + "/files";
								}
								String path = basePath + dirName + "/" + df.format(currentDate);
								// System.out.println(path);
								FileUpload.createPath(path, newFileName);
								//生成图片

								file.transferTo(new File(basePath + fileUrl));
								// 生成图片缩略图
								if (Arrays.<String> asList(extMap.get("images").split(",")).contains(fileExt)) {
									String thumbTargetUrl = FileUtil.getThumbPath(basePath + fileUrl, 1);
									String middleTargetUrl = FileUtil.getThumbPath(basePath + fileUrl, 2);
									String bigTargetUrl = FileUtil.getThumbPath(basePath + fileUrl, 3);
									File targetFile = new File(thumbTargetUrl);
									targetFile.createNewFile();
									targetFile = new File(middleTargetUrl);
									targetFile.createNewFile();
									ImageUtil.resize(basePath + fileUrl, bigTargetUrl, 1920, 1080);
									ImageUtil.resize(basePath + fileUrl, middleTargetUrl, 1200, 800);
									ImageUtil.resize(basePath + fileUrl, thumbTargetUrl, 600, 300);
								}
							} catch (IllegalStateException e) {
								return AR.failed("文件上传失败：" + e.getMessage());
							} catch (IOException e) {
								return AR.failed("文件上传失败：" + e.getMessage());
							}
						}break;
					}

					FileEntry fileEntry = new FileEntry();
					User user = getUser();
					String userId = null;
					if (user != null) {
						userId = user.getId();
					}

					fileEntry.setFileExt(fileExt);
					if (Arrays.<String> asList(extMap.get("images").split(",")).contains(fileExt)) {
						fileEntry.setFileType("1");
					}else if (Arrays.<String> asList(extMap.get("medias").split(",")).contains(fileExt)) {
						fileEntry.setFileType("2");
					} else if (Arrays.<String> asList(extMap.get("files").split(",")).contains(fileExt)) {
						fileEntry.setFileType("3");
					} else if (Arrays.<String> asList(extMap.get("other").split(",")).contains(fileExt)) {
						fileEntry.setFileType("4");
					}
					fileEntry.setDirId(dirId);
					fileEntry.setUserId(userId);
					fileEntry.setDateCreate(currentDate);
					fileEntry.setFileSize(file.getSize());
					fileEntry.setRealFileName(file.getOriginalFilename());
					fileEntry.setFileUrl(fileUrl);
					if(isVodMode){
						fileEntry.setStoreMode("vod");
						if(StringUtil.isNotBlank(videoId)){
							fileEntry.setFileUrl(videoId);
						}
					}else{
						fileEntry.setStoreMode("oss");
					}
					fileEntryList.add(fileEntry);
				}
			}
			// 保存文件相关信息到文件列表中
			fileEntryList = fileEntryService.saveList(fileEntryList);
			return AR.ok(fileEntryList,"成功上传文件。");
		}
	}

	@ResponseBody
	@PostMapping(value = "/deleteFile")
	public AR deleteFile(Long fileId, String fileUrl) throws Exception {
		// 文件上传路径
//		String basePath = globalsConfigurations.getFileRootPath();
//
//		FileEntry fileEntry = null;
//		if (fileUrl != null && !fileUrl.equals("")) {
//			fileEntry = fileEntryService.getByFileUrl(fileUrl);
//		} else {
//			fileEntry = fileEntryService.getById(fileId);
//		}
		try {
//			String filePath = "";
//			if (fileEntry != null) {
//				filePath = basePath + fileEntry.getFileUrl();
//			} else {
//				filePath = basePath + fileUrl;
//			}
//			FileUtil.delFile(filePath);
//			// 删除缩略图
//			String thumbTargetUrl = FileUtil.getThumbPath(filePath, 1);
//			String middleTargetUrl = FileUtil.getThumbPath(filePath, 2);
//			String bigTargetUrl = FileUtil.getThumbPath(filePath, 3);
//			FileUtil.delFile(thumbTargetUrl);
//			FileUtil.delFile(middleTargetUrl);
//			FileUtil.delFile(bigTargetUrl);
		} catch (Exception e) {
			e.printStackTrace();
		}
//		if (fileEntry != null) {
//			return fileEntryService.deleteById(fileEntry.getId());
//		} else {
		return AR.ok("删除成功");
//		}
	}

	/**
	 * 百度编辑器controller
	 *
	 * @param request
	 * @param response
	 */
	@GetMapping(value = "/ueditor/upload")
	public void config(HttpServletRequest request, HttpServletResponse response)  throws Exception{
		response.setContentType("application/json");
		String rootPath = request.getSession().getServletContext().getRealPath("/");
		String saveRootPath = SystemConfigureUtil.get(SystemConstants.FILE_ROOT_PATH);
		if (StringUtil.isBlank(saveRootPath)) {
			saveRootPath = request.getSession().getServletContext().getRealPath("/");
		}
		String exec = new ActionEnter(request, rootPath, saveRootPath, Integer.valueOf(SystemConfigureUtil.get(SystemConstants.FILE_UPLOAD_MODE))).exec();
		@Cleanup PrintWriter writer = response.getWriter();
		writer.write(exec);
	}

	/**
	 * 获取文件上传进度
	 * @param request
	 * @return
	 */
	@ResponseBody
	@PostMapping("getUploadProgress")
	public AR getUploadProgress(HttpServletRequest request) throws Exception {
		return AR.ok(request.getSession().getAttribute("uploadStatus"));
	}
}
